﻿using Leeder.Logger;
using SPSAndong.Model;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SPSAndong.Handle
{
    /// <summary>
    /// Ups状态查询
    /// 请求: Q1<cr>，16进制表示：51 31 OD
    /// 响应，UPS: (208.4 000.0 208.4 034 59.9 2.05 35.0 00110000<cr>
    /// </summary>
    public class UpsHandle
    {
        /// <summary>
        /// 获取ups响应数据,定义ups数据接收委托
        /// </summary>
        /// <param name="data"></param>
        public delegate void DataReceived(UpsModel data);
        /// <summary>
        /// 委托事件
        /// </summary>
        public event DataReceived Received;
        /// <summary>
        /// 串口对象
        /// </summary>
        SerialPort comm;
        /// <summary>
        /// ups查询线程控制
        /// </summary>
        CancellationTokenSource cancel_ups;

        /// <summary>
        /// 日志
        /// </summary>
        public LogOperate LogObj => Log.GetLogger(this.GetType());

        /// <summary>
        /// 初始化Com
        /// </summary>
        public void InitCom()
        {
            /*
            try
            {
                comm = new SerialPort();
                comm.PortName = GolbalVariable.CurrentParamet.Port.ToString();
                comm.BaudRate = GolbalVariable.CurrentParamet.BaudRdate;
                comm.StopBits = (StopBits)GolbalVariable.CurrentParamet.StopBit;
                comm.Parity = (Parity)GolbalVariable.CurrentParamet.CheckMode;
                //comm.PortName = GolbalVariable.SerialPortConf.PortName;
                //comm.BaudRate = int.Parse(GolbalVariable.SerialPortConf.BaudRate);
                //comm.StopBits = (StopBits)GolbalVariable.SerialPortConf.StopBits;
                //comm.Parity = (Parity)GolbalVariable.SerialPortConf.CheckMode;
                comm.Open();
                comm.DiscardNull = false;
                comm.RtsEnable = true;
                comm.DataReceived += Comm_DataReceived;
                //ups启动查询查询线程
                cancel_ups = new CancellationTokenSource();
                Task.Factory.StartNew(SendData, cancel_ups.Token);
                LogObj.Info("ups启动查询线程已启动");
            }
            catch (Exception ex)
            {
                //NLoggerHelper.ERROR(ex.Message,ex);
                Received?.Invoke(new UpsModel() { QueryResult = false, ErrorMsg = ex.Message });
            }
            */
        }
        /// <summary>
        /// 关闭com线程
        /// </summary>
        public void CloseCom()
        {
            if (this.cancel_ups != null && !this.cancel_ups.IsCancellationRequested)
                this.cancel_ups.Cancel();
            if (comm != null && comm.IsOpen)
                comm.Close();
        }
        /// <summary>
        /// 接收串口数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                SerialPort sp = (SerialPort)sender;
                //接收数据
                string result = "";
                string str = "";
                do
                {
                    Thread.Sleep(20);
                    str = sp.ReadExisting();
                    result += str;

                } while (str.Length > 0);
                //此处只保存数据，将具体业务放到其他线程中处理
                //通过委托将数据传递至外层处理
                if (!string.IsNullOrEmpty(result))
                {
                    //过滤掉首字(
                    string data = result.Replace("(", "").Replace("\r", "|");
                    var da = data.Split('|');
                    if (da.Length > 0)
                    {
                        string[] state = da[0].Split(' ');
                        if (state.Length >= 8)
                        {
                            var outState = AnalysisUpsResponseData(state);
                            if (outState != null && outState.State != null)
                            {
                                Received?.Invoke(outState);
                            }
                        }
                    }
                }

            }
            catch (Exception ex)
            {
                //NLoggerHelper.ERROR(ex.Message, ex);
                Received?.Invoke(new UpsModel() { QueryResult = false, ErrorMsg = ex.Message });
            }
        }
        /// <summary>
        /// 查询UPS电源状态
        /// </summary>
        private async void SendData()
        {
            while (true)
            {
                //当控件销毁或者系统退出时，取消线程
                if (cancel_ups.Token.IsCancellationRequested)
                {
                    cancel_ups.Dispose();
                    break;
                }
                try
                {
                    byte[] res = new byte[3];
                    res[0] = 0x51;
                    res[1] = 0x31;
                    res[2] = 0x0D;
                    comm.Write(res, 0, res.Length);
                }
                catch (Exception ex)
                {
                    LogObj.Error(ex.Message);
                    Received?.Invoke(new UpsModel() { QueryResult = false, ErrorMsg = ex.Message });
                }
                //查询之后，线程休眠
                await Task.Delay(5000);

            }
        }
        /// <summary>
        /// 解析ups响应数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private UpsModel AnalysisUpsResponseData(string[] data)
        {
            try
            {
                UpsModel model = new UpsModel();
                model.InputVoltage = Convert.ToDecimal(data[0]);
                model.LastInputVoltage = Convert.ToDecimal(data[1]);
                model.OutputVoltage = Convert.ToDecimal(data[2]);
                model.Load = Convert.ToInt32(data[3]);
                model.InputFrequency = Convert.ToDecimal(data[4]);
                model.BatterycellVoltage = Convert.ToDecimal((Convert.ToDecimal(data[5]) * 6).ToString("#0.0"));
                model.Temperature = Convert.ToDecimal(data[6]);
                UpsState state = new UpsState();
                if (data.Length >= 8)
                {
                    if (data[7].Length == 8)
                    {
                        string us = data[7].ToString();
                        state.OTher1 = Convert.ToInt16(us.Substring(0, 1));
                        state.OTher = Convert.ToInt16(us.Substring(1, 1));
                        state.Testing = Convert.ToInt16(us.Substring(2, 1));
                        state.UpsBackup = Convert.ToInt16(us.Substring(3, 1));
                        state.UpsFault = Convert.ToInt16(us.Substring(4, 1));
                        state.BypassOutput = Convert.ToInt16(us.Substring(5, 1));
                        state.BatteryVoltage = Convert.ToInt16(us.Substring(6, 1));
                        state.CityElectricity = Convert.ToInt16(us.Substring(7, 1));
                        model.State = state;
                    }
                }
                return model;
            }
            catch (Exception ex)
            {
                LogObj.Error(ex.Message);
                Received?.Invoke(new UpsModel() { QueryResult = false, ErrorMsg = ex.Message });
            }
            return null;
        }
    }
}
